Implement Alaska Child Care Assistance Program (CCAP)#8320
Conversation
…icyEngine#8319) Adds parameters, variables, and tests for the Alaska CCAP program including PASS III (general subsidy) and PASS II (12-month post-ATAP transitional), with the full provider rate matrix and special-needs supplement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8320 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 2 21 +19
Lines 44 338 +294
==========================================
+ Hits 44 338 +294
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
- Fix SN supplement formula (was suppressed by charged_rate default) - Correct PDF page anchors (pass_2_transition_months, child support, rates) - Strip broken AAC URL fragments - Add #page=1 to FICS references in .py files - Add unit test for ak_ccap_parent_in_eligible_activity Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add SSI to AK CCAP countable unearned sources (Manual §4080-3.1.b) - Fix sweep-gap .py references (PASS pages, rate schedule page) - Strip broken AAC fragment + cite 7 AAC 45 for ATAP common variables - Add distinguishing test case for SN supplement formula Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Rename ATAP common variables with ak_ prefix (was_atap_recipient → ak_was_atap_recipient, months_since_atap_exit → ak_months_since_atap_exit) - Convert ak_ccap_charged_rate to pure input variable (drop circular formula that returned max_provider_rate) - Register Alaska CCAP in programs.yaml - Replace akleg.gov landing pages with direct Casetext section URLs (7 AAC 41.012, 41.060, 41.335, 41.350; chapter 45 for ATAP) - Extract ak_ccap_base_eligible (DRY across PASS II/III) - Drop unused parameters args from formulas - Tighten multi-sentence parameter descriptions to single sentence
Critical: - Replace dead Casetext URLs with akleg.gov Title 7 PDF page anchors (Casetext deprecated /regulation/ namespace; affects 23 files) - Fix special-needs supplement base: use authorized rate (min(charged, max_state_rate)) per Manual §4370-2, not max_state_rate. Extract ak_ccap_authorized_rate_per_child for use in both ak_ccap_benefit_per_child and ak_ccap_special_needs_supplement. - Drop activity-test OR-fallback that bypassed §4070-3 D "each parent" requirement. Simplify parent-counting logic. Should-fix: - Reword 5 parameter descriptions to match [State] [verb] ... [this X] under the [Full Program Name] program. - Tighten defined_for="ak_ccap_child_eligible" in special-needs supplement - Delete orphaned ak_ccap_dependents_in_care variable and test - Remove WHAT-style comments from countable_earned/unearned_income - Fix comment typos in integration.yaml (SMI threshold, copay band) - Rename misleading ak_ccap_age_group.yaml Case 2 Test coverage additions (13 new cases, 298 total): - Rate region: CHUGACH/COPPER_RIVER -> VALDEZ_CORDOVA (2019 split), Bethel, Juneau - Provider/care unit: licensed home FT_DAY Fairbanks, approved relative Bethel infant, licensed group home Aleutians East infant - PASS II 11-month boundary (last month inside window) - ak_ccap.yaml: non-AK household returns 0; mixed-status siblings - Special-needs supplement: charged-below-max case (verifies new base); undocumented disabled child - New ak_ccap_authorized_rate_per_child test file
- smi/amount.yaml: re-index thresholds 2-15 (was 1-13, mapping every family to next-larger family's SMI); fix transcription errors at sizes 11-14; add sizes 14p ($13,529) and 15p ($13,789); fix Manual citation href to #page=203 (was #page=230 §4080-2 K) - age_threshold/adult.yaml: fix Manual citation href to #page=203; add §4070-4 A reference for family-size definition - ak_ccap_smi_threshold.py: update docstring (FICS publishes through size 15, not 13) - Cascading test updates to match corrected SMI values across smi_threshold, smi_band, income_eligible, copay_rate, copay, ak_ccap, and integration tests Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…into ak-ccap # Conflicts: # uv.lock
- Replace AKCCAPRateRegion enum with direct County reuse; collapse Copper River → Chugach for shared Valdez-Cordova rate; UNKNOWN counties fall back to Anchorage. - Use is_tanf_enrolled (not ak_atap > 0) for PASS I copay waiver, breaking the ak_ccap_copay ↔ ak_atap ↔ ak_ccap circular dependency. - Inline ak_ccap_smi_band into ak_ccap_copay_rate; drop redundant /MONTHS_IN_YEAR (bare period auto-divides annual hhs_smi). - Fix ak_ccap_max_provider_rate_per_child day-vs-month selection (was based on attending_days > 0; now based on schedule type). - Rename rate-region YAML keys to full County names (ANCHORAGE → ANCHORAGE_MUNICIPALITY_AK, VALDEZ_CORDOVA → CHUGACH_CENSUS_AREA_AK, etc.). - Backdate all CCAP parameters from 2022-02-21 → 2022-01-01. - Set all test periods to 2022-01; add UNKNOWN-fallback and non-AK defined_for test cases. - Replace artificial $120K/yr childcare expense placeholders with realistic AK family costs ($9.6K–$36K/yr by scenario). - TANF/SN tests use explicit is_tanf_enrolled / ssi: 0 inputs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Fix reference title/page mismatches and AAC section-title fidelity in smi_rate.yaml, adult.yaml, earned_sources.yaml, unearned_sources.yaml, supplement_multiplier.yaml. - Reorganize 18 CCAP test files into benefit/, copay/, eligibility/, income/, rates/ subfolders matching the variable layout; integration.yaml stays at program root. - Merge ak_ccap_excluded_income.yaml (5 cases) into ak_ccap_countable_income.yaml as Cases 10-14; drop the standalone file. - Clarify modeled scope in changelog and programs.yaml notes: PASS II/III modeled; PASS I (ATAP-bundled) and PASS IV (OCS protective services) not modeled. All 136 tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ak_ccap_rate_region previously returned a value from the full US County enum (3,175 values). Every parameter breakdown lookup ran County.encode() against all 3,175 candidates per person, even though the AK CCAP rate matrix has only 29 region keys. This made the AK CCAP test suite take ~10 minutes (max_provider_rate_per_child alone took 144s for 20 cases). Introduce AKCCAPRateRegion (29 values, matching the keys already in the 4 rate parameter YAMLs) and have ak_ccap_rate_region map county_str into it. The Copper River → Chugach collapse and the UNKNOWN/non-AK fallback to Anchorage are preserved. YAMLs do not need to change: the new enum's value names match the existing parameter keys. Results: - Full AK CCAP suite: ~10 min → 12.5s (~48× faster) - max_provider_rate_per_child: 144s → 5.04s (28.6×) - benefit/: 199s → 7.08s (28×) - 136/136 tests still pass Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Note on SMI source:
|
PavelMakarchuk
left a comment
There was a problem hiding this comment.
PR #8320 — AK Child Care Assistance Program (CCAP) — Full Review Report
Author: hua7450
Closes: #8319
Scope: New Alaska CCAP program covering PASS II + PASS III tracks (CCDF-funded). ~50 files, ~8,488 line diff. CI all green.
Recommended severity: COMMENT
The implementation is regulatorily sound: all spot-checked parameter values match the FICS Sliding Fee Scale, the HHS State Median Income table, the AK Child Care Rate Schedule, and 7 AAC 41. No value mismatches were found. All findings below are polish, documentation, or known Phase-1 scope limitations rather than blockers.
Source Documents
/tmp/review-program-context.md— PR context/tmp/review-program-pdf-manifest.md— PDF manifest/tmp/review-program-regulatory.md— regulatory survey/tmp/review-program-references.md— reference audit/tmp/review-program-code.md— code patterns review/tmp/review-program-tests.md— test coverage/tmp/review-program-pdf-1.md— eligibility audit/tmp/review-program-pdf-2.md— income + copay audit/tmp/review-program-pdf-3.md— provider rates audit
CRITICAL (Must Fix)
1. supplement_multiplier = 2 mismatches regulation language
- Where:
gov/states/ak/dhs/ccap/special_needs/supplement_multiplier.yaml, used byak_ccap_special_needs_supplement.py - Regulation: 7 AAC 41.060(b) authorizes a special-needs supplement of up to 100% of the regional base rate.
- Issue: The parameter is stored as
2.0and the formula uses(multiplier - 1) * base_rateto back out the additional supplement. The math is correct (PDF-3 confirms), but a reviewer comparing the YAML to the regulation sees2against a "100% cap" and reads a mismatch. - Recommended fix: Rename to
supplement_ratewith value1.0(representing the 100% cap) and simplify the formula tosupplement_rate * base_rate. No output change.
SHOULD ADDRESS
Eligibility scope gaps (PDF-1)
The Phase-1 activity / need-for-care test is narrower than 7 AAC 41.310–.360 and the CCAP Manual §4060–4070:
- Job-search 3-month grace period not modeled (7 AAC 41.310(a)(2)).
- Job training collapsed under
is_full_time_student; regulation treats it as a distinct qualifying activity. - Mid-period turn-13 rule not modeled — child remains eligible through end of authorization period.
- Grades 1–12 exclusion during school hours (7 AAC 41.350(c)) not implemented.
- Protective-services pathway (§4070-3) not implemented — bypasses income and activity tests.
- Physical-presence-in-state requirement not enforced.
These are known Phase-1 limitations; should be documented in the changelog and ideally in a code comment on ak_ccap_eligible.
Income / countable income (PDF-2, code review)
unearned_sources.yamldescription is 3 sentences with caveats — move caveats to a YAML comment so the rendered description is a single clean sentence.- 13 unearned income types from CCAP Manual §4080-3 are not modeled (royalties, ANCSA distributions, etc.). Several have no direct PE variable analog. Document as known under-implementation in the changelog and a YAML comment.
- Confirm farm income (§4080-2 J) is captured via PE's
self_employment_income. - Countable income variables use a manual sum loop where the
add()aggregation pattern would be cleaner and follow PE conventions.
Microsimulation behavior
Bare-input variables (*_provider_type, *_care_schedule, *_charged_rate, county_str) default to 0 in microsim, so every AK family computes a 0 subsidy until the dataset is enhanced. This is intentional for Phase 1 but should be called out in the changelog.
Tests (PDF-2, tests review)
- SMI boundary uses strict
<rather than<=; add an at-cap test. - Unearned-source coverage tests do not exercise each
unearned_sourcesflag independently. - Copay boundary tests missing at the 0.73 and 0.01 sliding-scale endpoints.
- Special-needs supplement and copay should have an independence test (changing one does not change the other).
References
- Rate-region YAMLs anchor only
#page=1, but the Rate Schedule PDF has 4 pages. Anchor the actual page per region. age_threshold/adult.yamlcites §4080-1; §4080-1 does not state the 18-year threshold — relocate the citation or use the correct section.age_threshold/child.yamltitle is missing the(a)(1)subsection of 7 AAC 41.350.
SUGGESTIONS
- Per-child CC51 supplement percentage — currently defaults everyone to the 100% cap; consider modeling the actual approved percentage which may be lower.
- PASS I/II/III copay distinction (§4370-1) — co-pay schedule varies by track; current model uses a single schedule.
- Two-provider combined maximum (§4370-2) — not enforced.
- Registration fee (§4370-4) — not modeled.
- Rename
ak_ccap_special_needs_supplement— it returns the regulatory maximum, not necessarily the actual supplement received. - Add inline comment in
ak_ccap_special_needs_supplement.pyexplaining the(multiplier - 1)transformation (or remove it via the rename above). - Add inline comment on the silent Anchorage fallback when
county_stris unrecognized — make the fallback explicit.
Confirmed Correct (Audit Spot-Checks)
- All 10 sliding-scale brackets verified against the FICS Sliding Fee Scale.
- 85% SMI cap matches 7 AAC 41.335(b).
- Family-of-4 monthly SMI $8,673 matches the HHS State Median Income table.
- Child age <13 confirmed by 7 AAC 41.350(a)(1) and Manual §4070-2.
- Special-needs cap <13 confirmed by 7 AAC 41.060(a).
- 29 rate regions in
AKCCAPRateRegionenum match the Rate Schedule (Copper River correctly collapsed into Chugach). - 4 care schedules × 4 age groups (Infant 0–12, Toddler 13–35, Preschool 36–59, School-Age 60+) match the Rate Schedule.
- 7 spot-checked rate cells match to the dollar.
min(authorized, charged)semantics correct at both per-child and household level.- Special-needs supplement math is arithmetically correct (100% cap of base rate).
ak_child_care_subsidiescorrectly wired into the federalchild_care_subsidiesaggregate.- Custom
AKCCAPRateRegionenum (avoiding US County) yields ~50× performance improvement, cleanly isolated.
Validation Summary
| Area | Status | Notes |
|---|---|---|
| Sliding-scale brackets (10) | PASS | Match FICS exactly |
| 85% SMI cap | PASS | 7 AAC 41.335(b) |
| HHS SMI table | PASS | Family of 4 = $8,673/mo |
| Child age threshold (<13) | PASS | 7 AAC 41.350(a)(1) |
| Special-needs age cap | PASS | 7 AAC 41.060(a) |
| Rate region enum (29) | PASS | Copper River → Chugach correct |
| Care schedule × age (4×4) | PASS | Matches Rate Schedule |
| Rate cell spot-checks (7) | PASS | Exact-to-dollar |
min(authorized, charged) |
PASS | Per-child and household |
| Special-needs math | PASS | Output correct |
| Federal aggregation wiring | PASS | Routed into child_care_subsidies |
supplement_multiplier naming |
FAIL | Value 2 vs regulation "100% cap" — rename only |
| Eligibility scope (6 items) | PARTIAL | Phase-1 limitations; document |
| Unearned income coverage | PARTIAL | 13 §4080-3 items unmodeled |
| Reference anchors | PARTIAL | Rate-region pages, adult/child age citations |
| Test boundary coverage | PARTIAL | SMI <=, copay endpoints, independence |
| Microsim default-0 inputs | KNOWN | Documented Phase-1 limitation |
| Performance optimization | PASS | Enum strategy ~50× faster |
Recommended Severity: COMMENT
No output values are wrong, no references are broken, all audit spot-checks pass, and the performance design is sound. The supplement_multiplier rename is worth landing for regulator-readability but produces identical numbers. Eligibility narrowness and unearned-income coverage are documented Phase-1 scope, appropriate to ship and iterate on.
Apply review feedback as documentation/clarity changes — no formula changes: Parameters - supplement_multiplier.yaml: rewrite description to make (multiplier-1) offset explicit; add 7 AAC 41.060(b) "100%" secondary reference - age_threshold/adult.yaml: add AS 25.20.010 (Alaska age of majority) - age_threshold/child.yaml: include 7 AAC 41.350(a)(1) subsection - rates/*.yaml: broaden #page=1 to pp.1-4, backdate rates start to 2021-12-01 (Rate Schedule effective date), add underscores to 4-digit values - income/smi_rate.yaml: lead with 7 AAC 41.335 / §4080-1 - countable_income/unearned_sources.yaml: single-sentence description; move caveats to YAML comments - copay/sliding_scale.yaml: clean awkward parenthetical - Normalize Manual citation style to §XXXX across files Variables (documentation only — no formula changes) - ak_ccap_income_eligible.py: comment SPMUnit vs §4070-4 family-size simplification - ak_ccap_parent_in_eligible_activity.py: comment OR-fallback to federal CCDF activity test as deliberate widening - ak_ccap_charged_rate.py: clarify input-only role in label/docs - ak_ccap_special_needs_supplement.py: relabel as maximum supplement (CC51 per-case authorization unobserved) - ak_ccap_countable_income.py: comments for unmodeled §4080-4 B (catastrophic medical) and §4080-4 C (educational); refactor into named locals - ak_ccap.py: comment that §4370-4 registration fee is paid State->provider Tests (+49 cases, 136 -> 185) - New regions file: one case per untested AK rate region - max_provider_rate matrix: fill 3 underused provider types x care schedules - ak_ccap_income_eligible.yaml: 85% SMI boundary pair + family-of-6 - ak_ccap_copay_rate.yaml: pin all 8 inner copay bracket boundaries - ak_ccap_eligible.yaml: assets exactly \$1,000,000 - ak_ccap_copay.yaml: is_disabled toggle pair (copay unchanged) - integration.yaml: intermediate-value pins on Cases 3 and 4 All 185 AK CCAP tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Review-feedback fixes appliedCommit: Should-Address (18) ✅
Suggestions (9) ✅
Critical 🟢None — review found zero critical issues; all 8 PDF-audit + code-validator agents confirmed no value mismatches, no hard-coded values, no reinvented variables, no formula errors. Verification
Ready for re-review. |
|
@hua7450 lgtm if the changes made sense |
Summary
Implements Alaska Child Care Assistance Program (CCAP), the state's CCDF-funded child care subsidy program administered as Parents Achieving Self-Sufficiency (PASS) under the Alaska Department of Health, Division of Public Assistance, Child Care Program Office.
This PR covers PASS III (general subsidy population) and PASS II (12-month transitional post-ATAP), with the full provider rate matrix and Alaska IN! special-needs supplement.
Closes #8319
Regulatory Authority
Program Overview
Eligibility
ak_ccap_child_age_eligible(age < p.age_threshold.child)where(is_disabled, age < p.age_threshold.special_needs, ...)defined_for = StateCode.AKak_ccap_parent_in_eligible_activity(all-parents-qualify; falls back tomeets_ccdf_activity_test)ak_ccap_income_eligible(countable_income <= ak_ccap_smi_threshold)is_ccdf_asset_eligible+ stateeligibility/asset_limit.yaml($1M)is_ccdf_immigration_eligible_child(parent citizenship not evaluated, per regulation)ak_ccap_eligiblecovers both categories — PASS II and PASS III share the same 85% SMI + $1M asset rule. PASS II's 12-month post-ATAP time limit is not enforced (single-period simplification; PolicyEngine cannot track months-since-ATAP-exit).spm_unit_size(broader than the Manual's "parents + minor children"; documented simplification — may overstate family size in extended-family households)Rate Region (refactored)
ak_ccap_rate_regionreuses the existingCountyenum directly instead of maintaining a parallel rate-region enum. The variable is keyed oncounty_strand returns aCountyvalue.COPPER_RIVER_CENSUS_AREA_AKintoCHUGACH_CENSUS_AREA_AK, so both successors share the single Valdez-Cordova rate column still published on the Provider Rate Schedule.ANCHORAGE_MUNICIPALITY_AKso downstream rate lookups always hit a valid AK borough key.licensed_center,licensed_group_home,licensed_home,approved_relative_in_home) key region breakdowns on full County names (e.g.,ANCHORAGE_MUNICIPALITY_AK).Income & Copay Calculation
ak_ccap_smi_thresholdmultiplies HHS SMI by family size byincome/smi_rate.yaml(0.85). HHS SMI matches the FICS table at every AK family size to within rounding.ak_ccap_copay(SPMUnit/MONTH) applies once at the family level (Manual §4080).ak_ccap_copaychecksis_tanf_enrolled(rather thanak_atap > 0) to break the circular dependencyak_ccap_copay → ak_atap → childcare_expenses → ak_ccap. ATAP is Alaska's TANF, so the family-level TANF enrollment flag is the right semantic match for the PASS I waiver under Manual §4040-3 D.employment_income,self_employment_income(adults only — child earned income excluded per Manual §4080-1 PDF p.203)addslists, so they flow around CCAP countable income naturallyak_ccap_child_support_paid_deductionsubtracts legally-obligated payments to non-CCAP family membersBenefit Calculation
ak_ccap_benefit_per_child, Person/MONTH):min(provider_charged_rate, state_max_provider_rate) − family_copay_share + special_needs_supplementak_ccap_max_provider_rate_per_child): looked up fromrates/{provider_type}.yamlindexed by[care_unit][region][age_group]. Day-based schedules (FT_DAY/PT_DAY) multiply the per-day rate bychildcare_attending_days_per_month; month-based schedules (FT_MONTH/PT_MONTH) use the flat monthly rate.ak_ccap_dependents_in_care); applied once total per family (Manual §4080)ak_ccap_special_needs_supplement=(supplement_multiplier − 1) × authorized_ratewithsupplement_multiplier = 2, so the maximum supplement equals the authorized rate (= the 100% cap in 7 AAC 41.060(b)). The supplement is added OUTSIDE themin(charge, max_rate)cap per regulation wording ("in addition to").ANCHORAGE_MUNICIPALITY_AKcolumn underlicensed_group_home.ak_child_care_subsidies(SPMUnit/YEAR) sums the 12 monthlyak_ccapvalues; registered ingov.hhs.ccdf.child_care_subsidy_programsto feed the federalchild_care_subsidiesrollup.Files Added/Changed
policyengine_us/parameters/gov/states/ak/dpa/ccap/(age_threshold, age_group, copay, eligibility, income/countable_income, rates, special_needs) + 1 line ingov/hhs/ccdf/child_care_subsidy_programs.yaml. All parameter start dates set to2022-01-01.policyengine_us/variables/gov/states/ak/dpa/ccap/(benefit, copay, eligibility, income, rates). The interimak_ccap_smi_bandwas inlined intoak_ccap_copay_rate. PASS II vs PASS III are not separate code branches — a singleak_ccap_eligiblecovers both categories (see Eligibility table above).policyengine_us/tests/policy/baseline/gov/states/ak/dpa/ccap/+ 2 in ATAP common; 136 tests, all passing.changelog.d/ak-ccap.added.mdTest Realism
All tests use period
2022-01(matching parameter effective dates). Test scenarios reflect real-life Alaska families:ssi: 0explicitly to isolate SN supplement logic from SSI deeming mathis_tanf_enrolled: trueexplicitly (matches the PASS I waiver condition the code now uses)Requirements Coverage
is_disabled, not tracked)Not Modeled (by design)
Historical Notes
2022-01-01to cleanly cover the schedule's first calendar year onwardTest Plan
make formatclean